<template>
  <div class="demo-container">
    <h2 class="demo-title">Vue 3 响应式系统高级演示</h2>
    
    <div class="demo-tabs">
      <div 
        v-for="tab in tabs" 
        :key="tab.id"
        class="tab-button"
        :class="{ active: activeTab === tab.id }"
        @click="activeTab = tab.id"
      >
        {{ tab.name }}
      </div>
    </div>
    
    <div class="tab-content">
      <!-- 基础响应式 -->
      <div v-show="activeTab === 'basic'" class="tab-pane">
        <div class="demo-grid">
          <div class="demo-card">
            <h3 class="card-title">ref 响应式引用</h3>
            <div class="demo-content">
              <p>ref 用于创建一个响应式的引用类型数据，可以是任何 JavaScript 类型。</p>
              <div class="demo-controls">
                <input v-model="counter" type="number" class="form-input">
                <button @click="increment" class="btn btn-primary">增加</button>
                <button @click="decrement" class="btn btn-secondary">减少</button>
              </div>
              <p class="demo-result">当前值: <strong>{{ counter }}</strong></p>
              <p class="demo-result">双倍值: <strong>{{ counter * 2 }}</strong></p>
            </div>
          </div>
          
          <div class="demo-card">
            <h3 class="card-title">reactive 响应式对象</h3>
            <div class="demo-content">
              <p>reactive 用于创建一个响应式的对象或数组。</p>
              <div class="form-group">
                <label>用户名:</label>
                <input v-model="user.name" type="text" class="form-input">
              </div>
              <div class="form-group">
                <label>年龄:</label>
                <input v-model.number="user.age" type="number" class="form-input">
              </div>
              <div class="form-group">
                <label>邮箱:</label>
                <input v-model="user.email" type="email" class="form-input">
              </div>
              <p class="demo-result">用户信息: {{ JSON.stringify(user) }}</p>
            </div>
          </div>
        </div>
      </div>
      
      <!-- 高级响应式 -->
      <div v-show="activeTab === 'advanced'" class="tab-pane">
        <div class="demo-grid">
          <div class="demo-card">
            <h3 class="card-title">shallowRef / shallowReactive</h3>
            <div class="demo-content">
              <p>浅层响应式，只跟踪顶层属性的变化。</p>
              <div class="form-group">
                <label>浅层对象名称:</label>
                <input v-model="shallowObject.name" type="text" class="form-input">
              </div>
              <div class="form-group">
                <label>浅层对象嵌套属性:</label>
                <input v-model="shallowObject.details.title" type="text" class="form-input">
                <button @click="updateShallowDetails" class="btn btn-primary">更新嵌套属性</button>
              </div>
              <p class="demo-result">浅层对象: {{ JSON.stringify(shallowObject) }}</p>
            </div>
          </div>
          
          <div class="demo-card">
            <h3 class="card-title">readonly / isReadonly</h3>
            <div class="demo-content">
              <p>创建只读的响应式代理。</p>
              <p class="demo-result">只读用户: {{ JSON.stringify(readonlyUser) }}</p>
              <button @click="tryUpdateReadonly" class="btn btn-warning">尝试更新</button>
              <p class="demo-result" :class="{ 'text-error': updateError }">
                {{ updateMessage }}
              </p>
            </div>
          </div>
        </div>
      </div>
      
      <!-- 计算属性和监听 -->
      <div v-show="activeTab === 'computed'" class="tab-pane">
        <div class="demo-grid">
          <div class="demo-card">
            <h3 class="card-title">计算属性高级用法</h3>
            <div class="demo-content">
              <p>带有 getter 和 setter 的计算属性。</p>
              <div class="form-group">
                <label>基础价格:</label>
                <input v-model.number="basePrice" type="number" class="form-input">
              </div>
              <div class="form-group">
                <label>折扣 (0-100):</label>
                <input v-model.number="discount" type="range" min="0" max="100" class="form-input">
                <span>{{ discount }}%</span>
              </div>
              <div class="form-group">
                <label>最终价格:</label>
                <input v-model.number="finalPrice" type="number" class="form-input">
              </div>
              <p class="demo-result">节省金额: <strong>{{ savings }}</strong></p>
            </div>
          </div>
          
          <div class="demo-card">
            <h3 class="card-title">watchEffect 高级用法</h3>
            <div class="demo-content">
              <p>自动依赖追踪，适用于复杂副作用场景。</p>
              <div class="form-group">
                <label>搜索关键词:</label>
                <input v-model="searchQuery" type="text" class="form-input">
              </div>
              <div class="form-group">
                <label>搜索结果数量:</label>
                <input v-model.number="resultCount" type="number" min="1" max="20" class="form-input">
              </div>
              <div class="search-results">
                <div v-for="(result, index) in searchResults" :key="index" class="result-item">
                  结果 {{ index + 1 }}: {{ result }}
                </div>
              </div>
              <p class="demo-result">最后搜索时间: {{ lastSearchTime }}</p>
            </div>
          </div>
        </div>
      </div>
      
      <!-- 自定义组合函数 -->
      <div v-show="activeTab === 'composables'" class="tab-pane">
        <div class="demo-grid">
          <div class="demo-card">
            <h3 class="card-title">useLocalStorage 组合函数</h3>
            <div class="demo-content">
              <p>将状态持久化到 localStorage 的自定义组合函数。</p>
              <div class="form-group">
                <label>保存的用户名:</label>
                <input v-model="savedUsername" type="text" class="form-input">
              </div>
              <div class="form-group">
                <label>保存的偏好设置:</label>
                <select v-model="theme" class="form-input">
                  <option value="light">浅色模式</option>
                  <option value="dark">深色模式</option>
                  <option value="system">系统模式</option>
                </select>
              </div>
              <button @click="clearStorage" class="btn btn-danger">清除存储</button>
              <p class="demo-result">数据已保存到 localStorage</p>
            </div>
          </div>
          
          <div class="demo-card">
            <h3 class="card-title">useCounter 组合函数</h3>
            <div class="demo-content">
              <p>可复用的计数器逻辑封装。</p>
              <div class="counter-display">{{ count }}</div>
              <div class="counter-controls">
                <button @click="incrementCount" class="btn btn-primary">+</button>
                <button @click="decrementCount" class="btn btn-secondary">-</button>
                <button @click="resetCount" class="btn btn-warning">重置</button>
              </div>
              <div class="form-group">
                <label>步长:</label>
                <input v-model.number="countStep" type="number" class="form-input">
              </div>
            </div>
          </div>
        </div>
        
        <div class="demo-grid">
          <div class="demo-card">
            <h3 class="card-title">useMouse 组合函数</h3>
            <div class="demo-content">
              <p>跟踪鼠标位置的组合函数。</p>
              <div class="mouse-tracker">
                <div class="mouse-pointer" :style="{ left: mouseX + 'px', top: mouseY + 'px' }"></div>
              </div>
              <p class="demo-result">鼠标坐标: ({{ mouseX }}, {{ mouseY }})</p>
            </div>
          </div>
          
          <div class="demo-card">
            <h3 class="card-title">useFetch 组合函数</h3>
            <div class="demo-content">
              <p>处理异步数据获取的组合函数。</p>
              <button @click="fetchData" class="btn btn-primary">获取数据</button>
              <div v-if="loading" class="loading">加载中...</div>
              <div v-else-if="error" class="error-message">{{ error }}</div>
              <div v-else-if="data" class="api-results">
                <h4>API 响应数据:</h4>
                <pre>{{ JSON.stringify(data, null, 2) }}</pre>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { 
  ref, reactive, computed, watchEffect, 
  shallowRef, shallowReactive, readonly, 
  isReadonly, nextTick 
} from 'vue';

export default {
  name: 'ReactivitySystemDemo',
  setup() {
    // 选项卡状态
    const activeTab = ref('basic');
    const tabs = [
      { id: 'basic', name: '基础响应式' },
      { id: 'advanced', name: '高级响应式' },
      { id: 'computed', name: '计算属性和监听' },
      { id: 'composables', name: '自定义组合函数' }
    ];
    
    // 基础响应式示例
    const counter = ref(0);
    const increment = () => counter.value++;
    const decrement = () => counter.value--;
    
    const user = reactive({
      name: '张三',
      age: 25,
      email: 'zhangsan@example.com'
    });
    
    // 高级响应式示例
    const shallowObject = shallowReactive({
      name: '浅层对象',
      details: {
        title: '嵌套属性'
      }
    });
    
    const updateShallowDetails = () => {
      // 由于是浅层响应式，需要替换整个嵌套对象才能触发更新
      shallowObject.details = {
        title: shallowObject.details.title
      };
    };
    
    const readonlyUser = readonly({
      name: '只读用户',
      role: 'admin'
    });
    
    const updateMessage = ref('');
    const updateError = ref(false);
    
    const tryUpdateReadonly = () => {
      try {
        // 尝试更新只读对象会在开发环境报错
        readonlyUser.name = '新名称';
        updateMessage.value = '更新成功（仅在生产环境可能静默失败）';
        updateError.value = false;
      } catch (e) {
        updateMessage.value = '无法更新只读对象';
        updateError.value = true;
      }
    };
    
    // 计算属性示例
    const basePrice = ref(100);
    const discount = ref(20);
    
    const finalPrice = computed({
      get: () => basePrice.value * (1 - discount.value / 100),
      set: (value) => {
        basePrice.value = value / (1 - discount.value / 100);
      }
    });
    
    const savings = computed(() => basePrice.value - finalPrice.value);
    
    // watchEffect示例
    const searchQuery = ref('');
    const resultCount = ref(5);
    const searchResults = ref([]);
    const lastSearchTime = ref('');
    
    watchEffect(() => {
      if (searchQuery.value.length > 0) {
        // 模拟搜索延迟
        const timer = setTimeout(() => {
          searchResults.value = Array.from({ length: resultCount.value }, 
            (_, i) => `${searchQuery.value} - 结果 ${i + 1}`);
          lastSearchTime.value = new Date().toLocaleTimeString();
        }, 300);
        
        // 清除副作用
        return () => clearTimeout(timer);
      } else {
        searchResults.value = [];
      }
    });
    
    // 自定义组合函数 - useLocalStorage
    function useLocalStorage(key, initialValue) {
      const storedValue = localStorage.getItem(key);
      const value = ref(storedValue ? JSON.parse(storedValue) : initialValue);
      
      watchEffect(() => {
        localStorage.setItem(key, JSON.stringify(value.value));
      });
      
      const clear = () => {
        localStorage.removeItem(key);
        value.value = initialValue;
      };
      
      return [value, clear];
    }
    
    const [savedUsername] = useLocalStorage('username', '默认用户');
    const [theme, clearTheme] = useLocalStorage('theme', 'light');
    const clearStorage = () => {
      localStorage.removeItem('username');
      clearTheme();
    };
    
    // 自定义组合函数 - useCounter
    function useCounter(initialValue = 0, step = 1) {
      const count = ref(initialValue);
      const stepRef = ref(step);
      
      const increment = () => { count.value += stepRef.value; };
      const decrement = () => { count.value -= stepRef.value; };
      const reset = () => { count.value = initialValue; };
      
      return {
        count,
        step: stepRef,
        increment,
        decrement,
        reset
      };
    }
    
    const counterState = useCounter(0, 1);
    const { count, step: countStep, increment: incrementCount, 
      decrement: decrementCount, reset: resetCount } = counterState;
    
    // 自定义组合函数 - useMouse
    function useMouse() {
      const mouseX = ref(0);
      const mouseY = ref(0);
      
      const updateMousePosition = (event) => {
        mouseX.value = event.clientX;
        mouseY.value = event.clientY;
      };
      
      // 添加事件监听
      watchEffect(() => {
        window.addEventListener('mousemove', updateMousePosition);
        return () => window.removeEventListener('mousemove', updateMousePosition);
      });
      
      return { mouseX, mouseY };
    }
    
    const { mouseX, mouseY } = useMouse();
    
    // 自定义组合函数 - useFetch
    function useFetch(url) {
      const data = ref(null);
      const loading = ref(false);
      const error = ref(null);
      
      const fetchData = async () => {
        loading.value = true;
        error.value = null;
        
        try {
          // 模拟API请求
          await new Promise(resolve => setTimeout(resolve, 1000));
          
          // 模拟响应数据
          data.value = {
            id: 1,
            name: '模拟数据',
            timestamp: new Date().toISOString(),
            status: 'success'
          };
        } catch (e) {
          error.value = '获取数据失败';
        } finally {
          loading.value = false;
        }
      };
      
      return { data, loading, error, fetchData };
    }
    
    const { data, loading, error, fetchData } = useFetch('https://api.example.com/data');
    
    return {
      // 选项卡
      activeTab,
      tabs,
      
      // 基础响应式
      counter,
      increment,
      decrement,
      user,
      
      // 高级响应式
      shallowObject,
      updateShallowDetails,
      readonlyUser,
      tryUpdateReadonly,
      updateMessage,
      updateError,
      
      // 计算属性和监听
      basePrice,
      discount,
      finalPrice,
      savings,
      searchQuery,
      resultCount,
      searchResults,
      lastSearchTime,
      
      // 自定义组合函数
      savedUsername,
      theme,
      clearStorage,
      count,
      countStep,
      incrementCount,
      decrementCount,
      resetCount,
      mouseX,
      mouseY,
      data,
      loading,
      error,
      fetchData
    };
  }
};
</script>

<style scoped>
.demo-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

.demo-title {
  font-size: 28px;
  color: #333;
  margin-bottom: 30px;
  text-align: center;
  font-weight: 600;
  animation: fadeInUp 0.5s ease-out;
}

.demo-tabs {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
  border-bottom: 2px solid #eee;
  overflow-x: auto;
  padding-bottom: 10px;
}

.tab-button {
  padding: 12px 24px;
  background: #f5f5f5;
  border: none;
  border-radius: 6px 6px 0 0;
  cursor: pointer;
  font-size: 16px;
  font-weight: 500;
  color: #666;
  transition: all 0.3s ease;
  white-space: nowrap;
}

.tab-button:hover {
  background: #e8e8e8;
  color: #333;
}

.tab-button.active {
  background: #42b983;
  color: white;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.tab-content {
  background: white;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}

.tab-pane {
  animation: fadeIn 0.3s ease;
}

.demo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
  gap: 20px;
  margin-bottom: 30px;
}

.demo-card {
  background: #fafafa;
  border-radius: 8px;
  padding: 24px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.demo-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.card-title {
  font-size: 20px;
  color: #333;
  margin-bottom: 16px;
  font-weight: 600;
  border-bottom: 2px solid #42b983;
  padding-bottom: 8px;
}

.demo-content {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.form-group label {
  font-weight: 500;
  color: #555;
  font-size: 14px;
}

.form-input {
  padding: 10px 12px;
  border: 2px solid #ddd;
  border-radius: 6px;
  font-size: 16px;
  transition: border-color 0.3s ease;
}

.form-input:focus {
  outline: none;
  border-color: #42b983;
  box-shadow: 0 0 0 3px rgba(66, 185, 131, 0.1);
}

.demo-controls {
  display: flex;
  gap: 10px;
  align-items: center;
}

.btn {
  padding: 10px 20px;
  border: none;
  border-radius: 6px;
  font-size: 16px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.3s ease;
}

.btn-primary {
  background: #42b983;
  color: white;
}

.btn-primary:hover {
  background: #3aa876;
  transform: translateY(-1px);
}

.btn-secondary {
  background: #6c757d;
  color: white;
}

.btn-secondary:hover {
  background: #5a6268;
  transform: translateY(-1px);
}

.btn-warning {
  background: #ffc107;
  color: #212529;
}

.btn-warning:hover {
  background: #e0a800;
  transform: translateY(-1px);
}

.btn-danger {
  background: #dc3545;
  color: white;
}

.btn-danger:hover {
  background: #c82333;
  transform: translateY(-1px);
}

.demo-result {
  background: #f8f9fa;
  padding: 12px;
  border-radius: 6px;
  border-left: 4px solid #42b983;
  margin: 10px 0;
}

.demo-result.text-error {
  border-left-color: #dc3545;
  color: #dc3545;
}

.counter-display {
  font-size: 48px;
  font-weight: bold;
  text-align: center;
  color: #42b983;
  margin: 20px 0;
}

.counter-controls {
  display: flex;
  justify-content: center;
  gap: 15px;
  margin: 20px 0;
}

.counter-controls .btn {
  width: 60px;
  height: 60px;
  font-size: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}

.mouse-tracker {
  width: 100%;
  height: 200px;
  border: 2px dashed #ddd;
  border-radius: 8px;
  position: relative;
  margin: 20px 0;
  background: #fafafa;
}

.mouse-pointer {
  width: 20px;
  height: 20px;
  background: #42b983;
  border-radius: 50%;
  position: absolute;
  transform: translate(-50%, -50%);
  pointer-events: none;
  transition: background 0.3s ease;
}

.search-results {
  max-height: 200px;
  overflow-y: auto;
  margin: 15px 0;
}

.result-item {
  padding: 10px;
  border-bottom: 1px solid #eee;
  background: white;
}

.result-item:last-child {
  border-bottom: none;
}

.loading {
  text-align: center;
  padding: 20px;
  color: #666;
  font-style: italic;
}

.error-message {
  color: #dc3545;
  padding: 10px;
  background: #f8d7da;
  border-radius: 6px;
  border: 1px solid #f5c6cb;
}

.api-results {
  background: white;
  padding: 15px;
  border-radius: 6px;
  border: 1px solid #ddd;
  max-height: 200px;
  overflow-y: auto;
}

.api-results pre {
  white-space: pre-wrap;
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 14px;
  color: #333;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .demo-grid {
    grid-template-columns: 1fr;
  }
  
  .demo-controls {
    flex-direction: column;
    align-items: stretch;
  }
  
  .demo-title {
    font-size: 24px;
  }
  
  .tab-button {
    padding: 10px 16px;
    font-size: 14px;
  }
  
  .counter-controls .btn {
    width: 50px;
    height: 50px;
    font-size: 20px;
  }
}
</style>